package main

import (
	"io"
	"log"
	"os"
	"time"
)

const (
	configPth = "./config.yaml"
)

func init() {
	//创建日志文件
	logF, err := os.OpenFile("main.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModePerm)
	if err != nil {
		log.Fatalln(err)
	}
	log.SetOutput(io.MultiWriter(os.Stdout, logF))

	//加载配置文件
	if !HasFile(configPth) {
		C.Save(configPth)
	}
	C.Load(configPth)
}

func main() {
	SetVirshDebug(C.Debug)

	//调试用，正常情况需要注释
	//worker(C.Shutdown)

	//一个小时唤醒一次，检查时间点，所以程序不是在正点进行工作的。
	ticker := time.NewTicker(time.Hour)
	for t := range ticker.C {
		if t.Hour() == C.AtHour {
			worker(C.Shutdown)
		}
	}
}

func worker(shutdown bool) {
	VMs, err := GetRunningVMs()
	if err != nil {
		log.Println(err)
		return
	}
	log.Printf("运行中的虚拟机：%v\n", VMs)

	//关闭所有的虚拟机，这会等待很长一段时间
	if shutdown {
		ShutdownVMs(VMs, true)
	}

	for _, vm := range VMs {
		if shutdown && !IsShutdown(vm) {
			log.Printf("虚拟机 %q 没有关闭，跳过自动快照工作\n", vm)
			continue
		}

		snaps, err := GetSnapshots(vm, C.Prefix)
		if err != nil {
			log.Println(err)
			continue
		}
		log.Printf("虚拟机 %q 的快照列表：%v\n", vm, snaps)

		//创建一个snapshot
		snapName := C.Prefix + time.Now().Format("20060102_150405")
		err = CreateSnapshot(vm, snapName)
		if err != nil {
			log.Println(err)
			continue
		}
		log.Printf("虚拟机 %q 创建了一个快照 %q\n", vm, snapName)

		//如果 snaps 数量超过了 C.MaxBackups，则删除多余的snapshot
		for i := 0; i <= len(snaps)-C.MaxBackups; i++ {
			if err = DeleteSnapshot(vm, snaps[i]); err != nil {
				log.Println(err)
				continue
			}
			log.Printf("虚拟机 %q 删除了一个快照 %q\n", vm, snaps[i])
		}
	}

	//启动所有的虚拟机
	if shutdown {
		StartVMs(VMs)
	}
}
